package com.anlogic.sdk.app.model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import org.apache.logging.log4j.Logger;
import org.eclipse.core.resources.IProject;

import com.anlogic.sdk.bsp.model.IPlatformProject;
import com.anlogic.sdk.bsp.utils.PlatformUtils;
import com.anlogic.sdk.utils.LogUtils;

public class ApplicationProject implements IApplicationProject {
	private static Logger logger = LogUtils.getLogger(ApplicationProject.class);
	
	private IProject iProject;
	private IPlatformProject bspProj;
	
	public static final String PROJECT_PROPERTY_FILE_NAME = ".ApplicationProject";

	public static final String PROJECT_NAME = "PROJECT_NAME";
	public static final String LANGUAGE_TYPE = "LANGUAGE_TYPE";
	public static final String BSP_NAME = "BSP_NAME";
	
	private String bspName;
	private String languageType;
	
	public ApplicationProject(IProject iProject) {
		this.iProject = iProject;
	}

	public static ApplicationProject createApplicationProject(IProject iProject, String bspName, String languageType) {
		ApplicationProject proj = new ApplicationProject(iProject);
		proj.iProject = iProject;
		proj.bspProj = PlatformUtils.getPlatformProject(bspName);
		
		proj.bspName = bspName;
		proj.languageType = languageType;
		proj.saveMetaData();
		return proj;
	}
	
	public String getName() {
		return iProject.getName();
	}

	public IProject getIProject() {
		return iProject;
	}
	
	public String getLanguageType() {
		return this.languageType;
	}
	
	public String getBspName() {
		return this.bspName;
	}
	
	public IPlatformProject getBspProj() {
		return this.bspProj;
	}
	
	public void setBspProj(IPlatformProject bspProj) {
		this.bspProj = bspProj;
		this.bspName = bspProj.getName();
	}
	
	public String getProperty(Properties p, String key) {
		return p.getProperty(key);
	}
	
	public void setProperty(Properties p, String key, String value) {
		p.setProperty(key, value);
	}
	
	public Properties getProperties(String backingFileName) {
		Properties p = new Properties();
		File f = new File(this.iProject.getFile(backingFileName).getLocation().toOSString());
		try {
			if (!f.exists())
				f.createNewFile();
			BufferedReader reader = new BufferedReader(new FileReader(f));
			try {
				while (true) {
					String line = reader.readLine();
					if (line == null)
						break;
					String[] nv = line.split("=");
					if (nv.length >= 2)
						p.setProperty(nv[0], nv[1]);
				}
			} finally {
				reader.close();
			}
		} catch (IOException e) {
			logger.error("Unable to load properties file {} for project {}", backingFileName, this.iProject.getName());
		}
		return p;
	}

	public Properties getDefaultProperties() {
		Properties prjMeta = getProperties(PROJECT_PROPERTY_FILE_NAME);
		return prjMeta;
	}
	
	public void saveMetaData() {
		Properties prjMeta = getProperties(PROJECT_PROPERTY_FILE_NAME);
		prjMeta.setProperty(PROJECT_NAME, this.getName());
		prjMeta.setProperty(LANGUAGE_TYPE, this.getLanguageType());
		prjMeta.setProperty(BSP_NAME, this.getBspName());
		saveProperties(prjMeta);
	}

	public void restoreMetaData() {
		Properties prjMeta = getProperties(PROJECT_PROPERTY_FILE_NAME);
		this.languageType = prjMeta.getProperty(LANGUAGE_TYPE);
		if (this.languageType == null)
			this.languageType = "unknown";
		this.bspName = prjMeta.getProperty(BSP_NAME);
		if (this.bspName == null)
			this.bspName = "unknown";
		this.bspProj = PlatformUtils.getPlatformProject(this.bspName);
	}
	
	public void saveProperties(Properties p) {
		File f = new File(this.iProject.getFile(PROJECT_PROPERTY_FILE_NAME).getLocation().toOSString());
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(f.getAbsolutePath()));
			try {
				for (Map.Entry<Object, Object> entry : p.entrySet()) {
					Object k = entry.getKey();
					Object v = entry.getValue();
					writer.write(k + "=" + v + "\n");
				}
			} finally {
				writer.close();
			}
		} catch (IOException e) {
			logger.error("Unable to save properties for Project {}", this.iProject.getName());
		}
	}
	
	public void writeToFile(String fileName, String txt) {
		File f = new File(this.iProject.getFile(fileName).getLocation().toOSString());
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(f.getAbsolutePath()));
			try {
				writer.write(txt);
			} finally {
				writer.close();
			}
		} catch (IOException e) {
			logger.error("Unable to save file for Project {}", this.iProject.getName());
		}
	}
}
